package com.zach.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 字符串操作辅助类
 * @author John
 * @edit 20120229
 */
public class StrUtil {
	private static Log log = LogFactory.getLog(StrUtil.class);
	private static boolean logDebugFlag = log.isDebugEnabled();
	/**
	 * 对指定的字符进行加密 
	 * @param src 要加密的字符
	 * @return 加密过的字符
	 */
	public static  String encryString(String src){
		if(logDebugFlag){
			log.debug("加密字符 原字符串："+src);
		}
		String str = SecurityUtil.stringToMD5(src);
		if(logDebugFlag){
			log.debug("加密后的字符串:"+str);
		}
		return str;
	}
	/**
	 * 判断是否为null或者为“null”
	 * @param str
	 * @return
	 */
	public static boolean isAnyNull(String str){
		if(null==str || str.equalsIgnoreCase("null"))
			return true;
		return false;
	}
	/**
	 * 
	 * @param src 要判断的源字符 串
	 * @return true:如源字符串是一个空串或者是一个Null串
	 */
	public static boolean isEmpty(String src){
		if(null == src || src.trim().length()==0)
			return true;
		return false;
	}
	/**
	 * one of the strs is blank or null return true;
	 * if str is null or str.length=0 return true;
	 * @param str
	 * @return
	 */
	public static boolean isBlankOrNull(String... str){
		if(null==str || str.length<1){
			return true;
		}
		for(String s:str){
			if(isBlankOrNull(s))
				return true;
		}
		return false;
	}
	/**
	 * 产生space个c
	 * @param c 要重复产生的字符（串）
	 * @param space 要产生的数量
	 * @return
	 */
	public static String dup(String c, Integer space) {
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<space;i++){
			sb.append(c);
		}
		return sb.toString();
	}
	/**
	 * 将一个字符串长度调整到width
	 * @param str 要调整的字符串
	 * @param width 最后的宽度，如果cut为True就是最大的宽度，如果不是就最小的宽度
	 * @param leftAlign 对齐方式，是否左对齐，如果为false就是右对齐
	 * @param cut 如果原字符串（str）长度超过设定宽度（width）时是否截断原字符串
	 * @return 调整后的字符串
	 */
	public static String toWidth(String str,Integer width,boolean leftAlign,boolean cut){
		if(str.length()>width && cut){ //原长度超过width
			return str.substring(0, width-1);
		}else if((str.length()>width && !cut) || str.length()==width){//原长超过width，不截;或者正好够长。
			return str;
		}else if(str.length()<width && !leftAlign){//右对齐
			return dup(" ", width-str.length())+str;
		}else{
			return str+dup(" ", width-str.length());
		}
	}
	/**
	 * 以左对齐、长度过长而不截的方式齐整字符串长度
	 * @param str 要调整的字符串
	 * @param width 要调整到的最小长度
	 * @return
	 */
	public static String toWidth(String str,Integer width){
		return toWidth(str, width, true, false);
	}
	/**
	 * 判断一个字符串(name)是否在另一个字符串集合(strs)中
	 * @param name 要比较的字符串，
	 * @param strs 字符串集合
	 * @return true:name保含在strs中。
	 * @edit John 20120229  修改方法名为contain。(原名cantain)
	 */
	public static boolean contain(String name,String... strs){
		for(String str:strs){
			if(str.equals(name)){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 从字符串src中最后删除字符c，如果src不是以c结尾的相当于什么都没有做
	 * @param src String
	 * @param c char
	 * @return 处理后的字符串，尾部不再有字符c
	 */
	public static String clearLastChar(String src,char c){
		StringBuilder sb = new StringBuilder(src);
		log.debug("源字符串 ："+src+"\t 要在尾部去除的字符"+c);
		
		while(sb.charAt(sb.length()-1) == c){
			sb.deleteCharAt(sb.length()-1);
		}
		log.debug("处理后的字符串："+sb.toString());
		return sb.toString();
	}
	@SuppressWarnings("deprecation")
	public static String webEncode(String str){
		log.debug("encode -->"+str);
		try {
			return URLEncoder.encode(URLEncoder.encode(str,"utf-8"),"utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			log.info("utf-8 编码 不支持");
			return URLEncoder.encode(URLEncoder.encode(str));
		}catch (NullPointerException ne) {
			log.info("传入的字符为null"+ne.getMessage());
			return "";
		}
	}
	@SuppressWarnings("deprecation")
	public static String webDecode(String str){
		if(isBlankOrNull(str)){
			return "";
		}
		log.debug("decode -->"+str);
		try {
			return URLDecoder.decode(str,"utf-8");
		} catch (UnsupportedEncodingException e) {
			log.info("utf-8 编码 不支持"+e.getMessage());
			return URLDecoder.decode(str);
		}
	}
	/**
	 * 返回一个字符串的描述局长信息，只给出特定长度的信息
	 * @author John 2011-5-5
	 * @param str 原始字符串，
	 * @param length 返回字符串的最大长度
	 * @return 最大长度为length的字符串
	 */
	public static String description(String str,int length){
		if(null!=str && str.length()>length){
			return str.substring(0, length-6)+"......";
		}
		return str;
	}
	/**
	 * 默认以Error方式输出信息,以简单的方式输出，只输出最上面的5行。
	 * @param ex 要记录日志的异常
	 * @edit John 20120229 现在可以用commons-logging下的log.error(msg,exception)来输出错误信息
	 */
	@Deprecated
	public static void writeException(Exception ex){
		writeException(ex, false);
	}
	/**
	 * 默认以Error方式输出信息
	 * @param ex 要记录日志的异常
	 * @param 是否输出全部错误堆栈信息
	 * @edit John 20120229 现在可以用commons-logging下的log.error(msg,exception)来输出错误信息
	 */
	@Deprecated
	public static void writeException(Exception ex,boolean full){
		StackTraceElement stes[] = ex.getStackTrace();
		int len = stes.length;
		if(!full){
			len = len>5?5:len;
		}
		StringBuilder sb = new StringBuilder();
		sb.append(ex.getMessage()).append('\n');
		if(null!=stes && stes.length>0){
			for(int i=0;i<len;i++){
				sb.append("\t").append("at ").append(stes[i].getClassName())
				.append(".").append(stes[i].getMethodName()).append("()")
				.append("[").append(stes[i].getFileName()).append("]")
				.append(stes[i].getLineNumber()).append("\n");
			}
		}
		log.error(sb.toString());
	}
}

